﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Script.Serialization;
using MyAlbum.Model;
using MyAlbum.Services;
using MyAlbum.Utility;
using System.Linq;
namespace PersonalAlbum.Controllers
{
    /// <summary>
    /// An entry contoller with replies feature - add,edit and view replies
    /// </summary>
    public class ReplyController : ApplicationController
    {
        private IDataService<Reply> _replyService;
        private IBlogService _blogService;
        public ReplyController()
            : this(ObjectFactory.GetInstance<IDataService<Reply>>(),
            ObjectFactory.GetInstance<IBlogService>())
        { }
        public ReplyController(IDataService<Reply> replyService, IBlogService blogService)
        {
            this._replyService = replyService;
            this._blogService = blogService;
        }

        /// <summary>
        /// Ajax method for adding reply
        /// </summary>
        /// <param name="reply">The reply data</param>
        /// <returns>A json result</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateCaptcha()]
        // [ValidateAn tiForgeryToken()]
        public ActionResult AddReply()
        {
            var model = (PersonalAlbumModel)ViewData.Model;
            if (model.Configuration.ShowAddRepliesBox)
            {
                WebLogger.Trace("add reply");
                try
                {
                    Reply reply = new Reply();
                    UpdateModel<Reply>(reply, "",
                        new string[] { "Body", "Email", "Subject", "UserName", "EntryId" },
                        new string[] { "Id" });


                    reply.TimeStamp = DateTime.UtcNow;
                    reply.IsApproved = model.Configuration.AutoApproveReplies;
                    ItemType itemType = (ItemType)Enum.Parse(typeof(ItemType), Request.Params["ItemType"]);
                    if (itemType == ItemType.Entry)
                    {
                        this._replyService.AddItem(reply, new ModelStateWrapper(ModelState));
                    }
                    else
                    {
                        this._blogService.AddComment(reply);
                    }
                    WebLogger.Trace("reply created");
                    if (model.Configuration.EmailOnReply)
                    {
                        try
                        {
                            new PostOffice(model.Configuration).NotifyNewReply(reply);
                            WebLogger.Trace("reply notified to admin");

                        }
                        catch (Exception e1)
                        {
                            WebLogger.LogError(e1, "error notifying new reply");
                        }
                    }
                    if (itemType == ItemType.Entry)
                    {
                        model.CurrentEntry = new Entry()
                        {
                            Replies = new List<Reply>() { reply }
                        };
                    }
                    else
                    {
                        model.Post = new PostEntry()
                        {
                            Replies = new List<Reply>() { reply }
                        };
                    }
                    string s = RenderPartialToString("ReplyItem", ViewData, this.ControllerContext);
                    //important!! do not use the Json() method of mvc on this method, as the line above has set
                    //some http headers and on that case the Json() method will throw an exception
                    JavaScriptSerializer js = new JavaScriptSerializer();
                    return new TextResult(js.Serialize(new { approved = reply.IsApproved.ToString(), replyHtml = s }));
                }
                catch (Exception e1)
                {
                    WebLogger.LogError(e1, "error adding reply");
                    return Utils.JavascriptError("");
                }
            }
            else
            {
                WebLogger.Warning("unauthorized entrance to add reply action");
                return Utils.JavascriptError("");
            }
        }

        public string RenderPartialToString(string userControl, ViewDataDictionary viewData, ControllerContext controllerContext)
        {
            System.IO.StringWriter writer=new System.IO.StringWriter();
            HtmlHelper h = new HtmlHelper(new ViewContext(controllerContext, new WebFormView("Index"), viewData, TempData,writer), new ViewPage());
            var blockRenderer = new BlockRenderer(controllerContext.HttpContext);
            RenderPartialExtensions.RenderPartial(h, userControl, viewData);
            //string s = blockRenderer.Capture(
            //    () => RenderPartialExtensions.RenderPartial(h, userControl, viewData)
            //);

            return writer.ToString();
        }


        [AcceptVerbs(HttpVerbs.Post)]
        // [ValidateAn tiForgeryToken()]
        [Authorize(Roles = RolesManager.AdminRoles)]
        public ActionResult UpdateReply(string replyId, string returnUrl)
        {
            WebLogger.Trace("update reply");
            var model = (PersonalAlbumModel)ViewData.Model;
            try
            {
                Reply r;
                ItemType itemType = (ItemType)Enum.Parse(typeof(ItemType), Request.Params["ItemType"]);
                if (itemType == ItemType.Post)
                {
                    r = this._blogService.GetPost(Request.Params["ItemID"]).Replies.Single(a => a.Id == replyId);
                }
                else
                {
                    r = this._replyService.GetItemById(replyId);
                }
                if (r != null)
                {
                    UpdateModel<Reply>(r, "Reply", new string[] { "Body", "Email", "EntryId", "IsApproved", "Subject", "UserName" });
                    if (itemType == ItemType.Entry)
                    {
                        this._replyService.UpdateItem(r, new ModelStateWrapper(ModelState));
                    }
                    else
                    {
                        this._blogService.UpdateComment(r);
                    }
                    WebLogger.Trace("reply updated");
                }
                else
                {
                    WebLogger.Warning("no reply found for editing:" + replyId);
                }
                TempData["message"] = model.Localize("Global.ReplyUpdated");
            }
            catch (Exception e1)
            {
                WebLogger.LogError(e1, "error updating reply");
                TempData["errorMessage"] = model.Localize("Global.Error");

            }
            if (string.IsNullOrEmpty(returnUrl))
            {
                return RedirectToAction("Index", "Entry");
            }
            else
            {
                return Redirect(returnUrl);
            }
        }

        [Authorize(Roles = RolesManager.AdminRoles)]
        public ActionResult DeleteReply(string replyId, string returnUrl)
        {
            WebLogger.Trace("delete reply");
            var model = (PersonalAlbumModel)ViewData.Model;
            try
            {
                ItemType itemType = (ItemType)Enum.Parse(typeof(ItemType), Request.Params["ItemType"]);
                if (itemType == ItemType.Post)
                {
                    this._blogService.DeleteComment(Request.Params["ItemID"], replyId);
                }
                else
                {
                    Reply r = this._replyService.GetItemById(replyId);
                    if (r != null)
                    {
                        this._replyService.DeleteItem(r);
                        WebLogger.Trace("reply deleted");
                    }
                    else
                    {
                        WebLogger.Warning("no reply found for delete " + replyId);
                    }
                }
                TempData["errorMessage"] = model.Localize("Global.ReplyDeleted");
            }
            catch (Exception e1)
            {
                WebLogger.LogError(e1, "error deleting reply");
                TempData["errorMessage"] = model.Localize("Global.Error");

            }
            if (string.IsNullOrEmpty(returnUrl))
            {
                return RedirectToAction("Index", "Entry");
            }
            else
            {
                return Redirect(returnUrl);
            }
        }
    }
}
